package com.jl.niuniu.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jl.api.CommonApi;
import com.jl.constants.SysConstants;
import com.jl.constants.UserRole;
import com.jl.enums.*;
import com.jl.exception.RRException;
import com.jl.mapper.AuthMapper;
import com.jl.mapper.PercentageMapper;
import com.jl.mapper.RoomMapper;
import com.jl.model.*;
import com.jl.model.niuniu.CoalitionNiuRoom;
import com.jl.model.niuniu.enums.*;
import com.jl.model.req.RoomIntoReq;
import com.jl.model.resp.InteractionResp;
import com.jl.model.resp.ReviewResp;
import com.jl.model.resp.RoomInfoResp;
import com.jl.model.resp.VoiceResp;
import com.jl.model.socket.RoomDetail;
import com.jl.model.vo.UserVo;
import com.jl.niuniu.mapper.CoalitionNiuRecordMapper;
import com.jl.niuniu.mapper.NiuNiuRoomMapper;
import com.jl.niuniu.model.*;
import com.jl.niuniu.model.dto.*;
import com.jl.service.GetUserInfoService;
import com.jl.service.RoomInfoService;
import com.jl.utils.CommonUtils;
import com.jl.utils.MySocketUtil;
import com.jl.utils.ObjectUtils;
import com.jl.utils.UserInfoContext;
import com.jl.utils.netty.JavaWebSocketClient;
import com.jl.utils.netty.JavaWebSocketFactory;
import com.jl.utils.niuniu.*;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.java_websocket.client.WebSocketClient;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class NiuNiuService implements CommonApi {

    private Integer coalitionId = 88888;

    @Resource
    private NiuNiuRoomMapper niuNiuRoomMapper;
    @Resource
    private GetUserInfoService getUserInfoService;
    @Resource
    private RoomInfoService roomInfoService;
    @Resource
    private CoalitionNiuRecordMapper coalitionNiuRecordMapper;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private PercentageMapper percentageMapper;
    @Resource
    private AuthMapper authMapper;
    @Resource
    private RedisTemplate<String,String> redisTemplate;

    public Object getParam() {
        try {
            NiuNiuParam niuNiuParam = CommonUtils.packParam(NiuNiuParam.class, AdvancedOptions.class, Bets.class, FlopRule.class, GameBegin.class, MaxRush.class, GameNumber.class,
                    PeopleNumber.class, PushInjection.class, RoomRate.class, SpecialCardType.class,SpecialCardType2.class, GameType.class);
            return niuNiuParam;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Object createRoom(Object object) {
        UserVo user = UserInfoContext.getUser();
        User userInfo = new User();
        userInfo.setId(user.getId());
        BigDecimal coin = getUserInfoService.getUserRealTime(userInfo);
        NiuNiuParamDto niuNiuParamDto = JSONObject.parseObject(JSONObject.toJSONString(object), NiuNiuParamDto.class);
        if (!user.getUserRole().equals(UserRole.管理员.getValue())){ //如果不是管理员,判断是否有足够的游戏币
            if (niuNiuParamDto.getRoomRate().equals(RoomRate.type1.getId())){
                if (!RoomRate.compareTo(RoomRate.type1,coin)){
                    throw new RRException("501","玩家金币不足,无法支付");
                }
            }
        }
        CoalitionNiuRoom coalitionRoom = new CoalitionNiuRoom();
        BeanUtils.copyProperties(niuNiuParamDto,coalitionRoom);
        RoomCreateResp roomCreateResp = new RoomCreateResp();
        roomCreateResp.setPlay(AdvancedOptions.typeStr(niuNiuParamDto.getAdvancedOptions()));
        try {
            CommonUtils.setParam(niuNiuParamDto,roomCreateResp);
            List<ParamVo> list = new ArrayList<>();
            if (("1,2".contains(roomCreateResp.getFlopRule().getId()))){
                SpecialCardType[] values = SpecialCardType.values();
                for (SpecialCardType value : values) {
                    setSpecialCardType(niuNiuParamDto, list, value.getId(), value.getDesc());
                }
            }else {
                SpecialCardType2[] values = SpecialCardType2.values();
                for (SpecialCardType2 value : values) {
                    setSpecialCardType(niuNiuParamDto, list, value.getId(), value.getDesc());
                }
            }
            roomCreateResp.setSpecialCardType(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (coalitionRoom.getId()!=null){ //编辑
            niuNiuRoomMapper.updateByPrimaryKeySelective(coalitionRoom);
        }else { //新增
            CoalitionRoom room = new CoalitionRoom();
            room.setCreateTime(new Date());
            room.setGameType("1");
            room.setCreateBy(user.getId());
            room.setStatus("1");
            if (niuNiuParamDto.getCoalitionId()==null){ //创建私人房间
                room.setPersonal("1");
                //扣除游戏币
                if (RoomRate.type1.getId().equals(niuNiuParamDto.getRoomRate())){
                    getUserInfoService.changeAccount(2,user.getId(),new BigDecimal(RoomRate.type1.getValue()));
                }
            }else {
                room.setPersonal("0");
            }
            roomMapper.insertUseGeneratedKeys(room);
            coalitionRoom.setCreateTime(new Date());
            coalitionRoom.setId(room.getId());
            if (niuNiuParamDto.getIntoCoin()==null){
                coalitionRoom.setIntoCoin(new BigDecimal(0));
            }
            niuNiuRoomMapper.insert(coalitionRoom);
            roomCreateResp.setId(room.getId());
        }
        //存REDIS
        roomInfoService.setRoomDetail(niuNiuParamDto);
        return roomCreateResp;
    }

    private void setSpecialCardType(NiuNiuParamDto niuNiuParamDto, List<ParamVo> list, String id, String desc) {
        if (!StringUtils.isEmpty(niuNiuParamDto.getSpecialCardType())) {
            String[] split = niuNiuParamDto.getSpecialCardType().split(",");
            for (String s : split) {
                if (id.equals(s)) {
                    ParamVo paramVo = new ParamVo(id, desc);
                    list.add(paramVo);
                }
            }
        }
    }

    @Override
    public Object recordQuery() {
        UserVo user = UserInfoContext.getUser();
        List<NiuRecordDto> records = coalitionNiuRecordMapper.selectRecord(user.getId());
//        for (NiuRecordDto niuRecordDto : records) {
//            for (NiuRecordDetailDto detail : niuRecordDto.getDetails()) {
//                String desc = CommonUtils.getEnumDescById(CardType.class, detail.getPokerType(), "getDesc");
//                detail.setPokerType(desc);
//            }
//        }
        return records;
    }

    @Override
    public Object getRoomDetail(Integer roomId) {
        NiuNiuParamDto niuNiuParamDto = getNiuRoomInfo(roomId);
        NiuRoomParamDto niuRoomParamDto = new NiuRoomParamDto();
        try {
            CommonUtils.setParam(niuNiuParamDto,niuRoomParamDto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return niuRoomParamDto;
    }

    @Override
    public Object playGame(RoomIntoReq roomIntoReq, RoomDetail roomDetail, ChannelHandlerContext channelHandlerContext,
                           ConcurrentHashMap<ChannelHandlerContext, ChcRoomInfo> chcRoom,ConcurrentHashMap<ChannelHandlerContext, WaCherInfo> waCher) {
        if (NiuAction.type2.getId().equals(roomIntoReq.getAction())){ //准备
            ready(roomIntoReq,roomDetail,channelHandlerContext,chcRoom,waCher);
        }else if (NiuAction.type3.getId().equals(roomIntoReq.getAction())) {
            poker(roomIntoReq,roomDetail,channelHandlerContext);
        }else if (NiuAction.type4.getId().equals(roomIntoReq.getAction())){
//            setAction(chcRoom,channelHandlerContext,NiuAction.type4);
            if (!roomDetail.getStatus().equals(GameStatus.type2.getId())){
                roomInfoService.sendErrorMessage(roomIntoReq, RoomAction.type106,channelHandlerContext);
                return null;
            }
            maxRush(roomIntoReq,roomDetail);
        }else if (NiuAction.type6.getId().equals(roomIntoReq.getAction())){
//            setAction(chcRoom,channelHandlerContext,NiuAction.type6);
            bets(roomIntoReq,roomDetail);
        }else if (NiuAction.type10.getId().equals(roomIntoReq.getAction())){
            brightCard(roomIntoReq,roomDetail);
        }else if (NiuAction.type12.getId().equals(roomIntoReq.getAction())){
            quit(roomIntoReq,roomDetail,channelHandlerContext);
        }else if (NiuAction.type18.getId().equals(roomIntoReq.getAction())){
            voice(roomIntoReq,roomDetail);
        }else if (NiuAction.type19.getId().equals(roomIntoReq.getAction())){
            interaction(roomIntoReq,roomDetail,channelHandlerContext);
        }else if (NiuAction.type997.getId().equals(roomIntoReq.getAction())){
            heartbeat(roomIntoReq,channelHandlerContext);
        }
        return null;
    }

    private void heartbeat(RoomIntoReq roomIntoReq, ChannelHandlerContext channelHandlerContext) {
        channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(roomIntoReq)));
    }

    private void voice(RoomIntoReq roomIntoReq, RoomDetail roomDetail) {
        VoiceResp voiceResp = new VoiceResp();
        voiceResp.setUserId(roomIntoReq.getUserId());
        voiceResp.setVoice(roomIntoReq.getActionValue());
        sendMessageToAll(roomIntoReq,roomDetail,toJsonString(voiceResp), NiuAction.type18);
    }

    private void interaction(RoomIntoReq roomIntoReq, RoomDetail roomDetail, ChannelHandlerContext channelHandlerContext) {
        JSONObject jsonObject = JSONObject.parseObject(roomIntoReq.getActionValue());
        Integer targetUser = jsonObject.getInteger("targetUser");
        String interaction = jsonObject.getString("interaction");
        InteractionResp interactionResp = new InteractionResp();
        interactionResp.setInteraction(interaction);
        interactionResp.setTargetUser(targetUser);
        interactionResp.setSendUser(roomIntoReq.getUserId());
        sendMessageToAll(roomIntoReq,roomDetail,toJsonString(interactionResp),NiuAction.type19);
    }

    @Override
    public Object review(Integer roomId) {
        List<ReviewResp> reviewResp = coalitionNiuRecordMapper.selectReview(roomId);
        for (ReviewResp resp : reviewResp) {
            List<Poker> pokers = JSONArray.parseArray(resp.getPokerJson(), Poker.class);
            resp.setPoker(pokers);
        }
        return reviewResp;
    }

    @Override
    public void quit(ChcRoomInfo chcRoomInfo, RoomDetail roomDetail,ChannelHandlerContext channelHandlerContext) {
        RoomIntoReq roomIntoReq = new RoomIntoReq();
        roomIntoReq.setUserId(chcRoomInfo.getUserId());
        roomIntoReq.setRoomId(chcRoomInfo.getRoomId());
        roomIntoReq.setGameType(chcRoomInfo.getType());
        quit2(roomIntoReq,roomDetail,channelHandlerContext);
    }

    private String getProperty(Object o,String name){
        String s = null;
        try {
            Object property = PropertyUtils.getProperty(o, name);
            if (property!=null){
                s = property.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    @Override
    public void trusteeship(ChcRoomInfo chcRoomInfo,RoomDetail roomDetail,ConcurrentHashMap<ChannelHandlerContext, ChcRoomInfo> chcRoom) {
        WebSocketClient channelFuture = null;
        JavaWebSocketClient instance = JavaWebSocketFactory.getInstance();
        if (instance!=null){
            channelFuture = instance.connect();
            RoomIntoReq roomIntoReq = new RoomIntoReq();
            roomIntoReq.setAction(RoomAction.type198.getId());
            roomIntoReq.setActionValue(toJsonString(chcRoomInfo));
            roomIntoReq.setUserId(chcRoomInfo.getUserId());
            roomIntoReq.setGameType(chcRoomInfo.getType());
            roomIntoReq.setRoomId(chcRoomInfo.getRoomId());
            channelFuture.send(toJsonString(roomIntoReq));
        }else {
            log.info("为什么没有对象?!");
        }
        roomDetail.getUserTrusteeship().put(chcRoomInfo.getUserId(),channelFuture);
        roomDetail.getUserTrusteeshipThread().put(chcRoomInfo.getUserId(),Thread.currentThread());
        log.info("我进来啦!!!!");
        RoomInfoResp roomInfoResp = new RoomInfoResp();
        roomInfoResp.setGameType(chcRoomInfo.getType());
        roomInfoResp.setRoomId(chcRoomInfo.getRoomId());
        roomInfoResp.setUserId(chcRoomInfo.getUserId());
        Object o = roomDetail.getUserInfo().get(chcRoomInfo.getUserId());
        log.info("chcRoom :{} ,userInfo:{}",chcRoomInfo,o);
        if (NiuAction.type2.getId().equals(getProperty(o,"action"))){ //所有人准之后立刻退备出有可能出现此情况
//            poker(roomIntoReq,roomDetail,chcRoomInfo.getChannelHandlerContext());
            trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type3,"");
        }
        if (NiuAction.type3.getId().equals(getProperty(o,"action"))){ //抢庄阶段
            trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type4,"0");
            NiuNiuParamDto niuRoomInfo = getNiuRoomInfo(chcRoomInfo.getRoomId());
            String banker = "0";
            try {
                banker = PropertyUtils.getProperty(roomDetail.getUserInfo().get(chcRoomInfo.getUserId()), "banker").toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if ("0".equals(banker)){
                String descById = Bets.getDescById(niuRoomInfo.getBets());
                String bets = descById.split("/")[0];
                sleep(500);
                trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type6,bets);
                sleep(500);
                trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type10,"");
            }else {
                sleep(5,channelFuture,roomDetail);
                trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type10,"");
            }
        }else if (NiuAction.type4.getId().equals(getProperty(o,"action"))){ //下注阶段
            sleep(9,channelFuture,roomDetail);
            log.info("此人是庄家吗,{}",getProperty(o,"banker"));
            if (getProperty(o,"banker").equals("1")){
                trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type10,"");
            }else {
                NiuNiuParamDto niuRoomInfo = getNiuRoomInfo(chcRoomInfo.getRoomId());
                String descById = Bets.getDescById(niuRoomInfo.getBets());
                String bets = descById.split("/")[0];
                trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type6,bets);
                sleep(500);
                trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type10,"");
            }
        }else if (NiuAction.type6.getId().equals(getProperty(o,"action"))){ //亮牌阶段
            sleep(9,channelFuture,roomDetail);
            trusteeshipMessage(roomDetail,roomInfoResp,channelFuture,NiuAction.type10,"");
        }else if (NiuAction.type10.getId().equals(getProperty(o,"action"))){
            sleep(9,channelFuture,roomDetail);
            channelFuture.send("");
        }
        RoomIntoReq roomIntoReq = new RoomIntoReq();
        BeanUtils.copyProperties(roomInfoResp,roomIntoReq);
        sleep(5000);
        quit2(roomIntoReq,roomDetail,chcRoomInfo.getChannelHandlerContext());
        channelFuture.close();
    }

    private void sleep(long time){
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void sleep(int time, WebSocketClient channelFuture,RoomDetail roomDetail){
        try {
            roomDetail.begin(time);
            wait(roomDetail);
            sleep(500);
        } catch (Exception e) {
            e.printStackTrace();
            channelFuture.close();
        }
    }

    @Override
    public void watcherQuit(WaCherInfo waCherInfo, RoomDetail roomDetail, ChannelHandlerContext ctx) {
        RoomIntoReq roomIntoReq = new RoomIntoReq();
        roomIntoReq.setGameType(waCherInfo.getGameType());
        roomIntoReq.setRoomId(waCherInfo.getRoomId());
        roomIntoReq.setUserId(waCherInfo.getUserId());
        quit2(roomIntoReq,roomDetail,ctx);
    }

    private void trusteeshipMessage(RoomDetail roomDetail,RoomInfoResp roomInfoResp,WebSocketClient channelFuture,NiuAction niuAction,String actionValue) {
        roomInfoResp.setAction(niuAction.getId());
        roomInfoResp.setActionValue(actionValue);
        if (channelFuture!=null){
            channelFuture.send(toJsonString(roomInfoResp));
        }else {
            log.info("该通道已关闭");
            return;
        }
        log.info("动作{}开始倒计时",niuAction.getId());
        roomDetail.begin(8);
        wait(roomDetail);
    }

    private void wait(RoomDetail roomDetail) {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        while (roomDetail.getCountDown().getCount()!=0){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    private void quit(RoomIntoReq roomIntoReq, RoomDetail roomDetail,ChannelHandlerContext channelHandlerContext) {
        CoalitionRoom coalitionRoom = roomMapper.selectByPrimaryKey(roomIntoReq.getRoomId());
        if ("1".equals(coalitionRoom.getPersonal())){ //私人
            if(roomIntoReq.getUserId().equals(coalitionRoom.getCreateBy())){ //房主无法退出
                roomInfoService.sendErrorMessage(roomIntoReq, RoomAction.type103,channelHandlerContext);
                return;
            }
        }
        if (GameStatus.type2.getId().equals(roomDetail.getStatus())&&roomDetail.getUserInfo().get(roomIntoReq.getUserId())!=null){ //已开始游戏无法退出游戏
            roomInfoService.sendErrorMessage(roomIntoReq,RoomAction.type199,channelHandlerContext);
            return;
        }else {
            //发送给所有人XX退出了房间
            quit2(roomIntoReq, roomDetail, channelHandlerContext);
        }
    }

    private void quit2(RoomIntoReq roomIntoReq, RoomDetail roomDetail, ChannelHandlerContext channelHandlerContext) {
        if (roomDetail.getUserInfo().get(roomIntoReq.getUserId())!=null){ //玩家
            sendMessageToAll(roomIntoReq,roomDetail,String.valueOf(roomIntoReq.getUserId()), NiuAction.type12);
            roomInfoService.quit(roomIntoReq,roomDetail,channelHandlerContext);
            roomInfoService.deleteRoomResult(roomIntoReq.getRoomId(),roomIntoReq.getUserId(),NiuGameResult.class);
            getUserInfoService.deleteUserPoker(roomIntoReq.getUserId());
            //redis删除在玩信息
            redisTemplate.opsForHash().delete(SysConstants.GAME_PLAYER_STATUS,roomIntoReq.getUserId().toString());
        }else { //观战
            //发送给所有人观战人数
            roomInfoService.quit(roomIntoReq,roomDetail,channelHandlerContext);
            roomIntoReq.setActionValue(String.valueOf(roomIntoReq.getUserId()));
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
            MySocketUtil.sendWatchCount(roomIntoReq,roomDetail);
        }
        log.info("xxx退出了游戏");
        channelHandlerContext.close();
    }

    private synchronized void brightCard(RoomIntoReq roomIntoReq, RoomDetail roomDetail) {
        roomIntoReq.setActionValue("1");
        Collection<NiuGameResult> result = roomInfoService.getRoomResult(roomIntoReq.getRoomId(), NiuGameResult.class);
        while (CollectionUtil.isEmpty(result) || result.size()!=roomDetail.getUserInfo().size()){
            try {
                Thread.sleep(500);
                result = roomInfoService.getRoomResult(roomIntoReq.getRoomId(), NiuGameResult.class);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        log.info("究极报错点!游戏结果:{}",result);
        log.info("究极报错点!用户是:{}",roomIntoReq.getUserId());
        NiuGameResult niuGameResult = result.stream().filter(a -> a.getId().equals(roomIntoReq.getUserId())).collect(Collectors.toList()).get(0);
        Object o = setProperty(roomIntoReq, roomDetail);
        try {
            PropertyUtils.setProperty(o,"poker",niuGameResult.getPoker());
        } catch (Exception e) {
            e.printStackTrace();
        }
        NiuNiuParamDto niuRoomInfo = getNiuRoomInfo(roomIntoReq.getRoomId());
        NiuCardResult niuCardResult = new NiuCardResult();
        niuCardResult.setId(roomIntoReq.getUserId());
        niuCardResult.setPoker(niuGameResult.getPoker());
        niuCardResult.setCardType(niuGameResult.getCardType());
        niuCardResult.setCardDesc(CardType.getEnumById(niuGameResult.getCardType()).getDesc());
        niuCardResult.setCardRate(CardUtils.getCardRate(niuRoomInfo.getFlopRule(),niuGameResult.getCardType()));
        sendMessageToAll(roomIntoReq,roomDetail,toJsonString(niuCardResult),NiuAction.type10);
        setUserAction(roomIntoReq,roomDetail,NiuAction.type10);
        //所有人亮牌后结算
        if (MySocketUtil.finish(roomDetail,NiuAction.type10.getValue())){
            List<CoalitionNiuRecord> records = new ArrayList<>();
            roomDetail.interrupt();
            for (NiuGameResult gameResult : result) {
                Object o1 = roomDetail.getUserInfo().get(gameResult.getId());
                User user = new User();
                user.setId(gameResult.getId());
                BigDecimal userRealTime = getUserInfoService.getUserRealTime(user);
                if (gameResult.getWin().compareTo(new BigDecimal(0))>0){ //赢
                    userRealTime = userRealTime.add(gameResult.getWin());
                    //如果赢钱, 抽成
                    BigDecimal percentage = roomInfoService.getPercentage();
                    BigDecimal my = percentage.multiply(gameResult.getWin()).setScale(1,BigDecimal.ROUND_HALF_UP);
                    BigDecimal proxyCoin = new BigDecimal("0");
                    User user2 = authMapper.selectByPrimaryKey(gameResult.getId());
                    if (user2.getProxyRate()!=null&&user2.getProxyRate().compareTo(new BigDecimal("0"))>0){
                        proxyCoin = my.multiply(new BigDecimal("0.8333")).multiply(user2.getProxyRate()).setScale(1, BigDecimal.ROUND_HALF_DOWN);
                    }
                    userRealTime = userRealTime.subtract(my);
                    CoalitionPercentage coalitionPercentage = new CoalitionPercentage();
                    coalitionPercentage.setCreateTime(new Date());
                    coalitionPercentage.setGameId(gameResult.getGameId());
                    coalitionPercentage.setPercentageCoin(my);
                    coalitionPercentage.setPercentageRate(percentage);
                    coalitionPercentage.setPercentageUser(gameResult.getId());
                    coalitionPercentage.setProxyCoin(proxyCoin);
                    percentageMapper.insertUseGeneratedKeys(coalitionPercentage);
                    try {
                        PropertyUtils.setProperty(o1,"coin",userRealTime);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else {
                    userRealTime = userRealTime.subtract(gameResult.getLose());
                    try {
                        PropertyUtils.setProperty(o1,"coin",userRealTime);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (userRealTime.compareTo(new BigDecimal(0))<0){
                    userRealTime = new BigDecimal(0);
                }
                user.setCoin(userRealTime);
                gameResult.setCoin(userRealTime);
                getUserInfoService.changeCoin(gameResult.getId(),userRealTime);
                //插入数据库
                CoalitionNiuRecord coalitionNiuRecord = new CoalitionNiuRecord();
                BeanUtils.copyProperties(gameResult,coalitionNiuRecord);
                coalitionNiuRecord.setId(null);
                coalitionNiuRecord.setUserId(gameResult.getId());
                coalitionNiuRecord.setCoalitionId(coalitionId);
                coalitionNiuRecord.setRoomId(roomIntoReq.getRoomId());
                coalitionNiuRecord.setPoker(toJsonString(gameResult.getPoker()));
                coalitionNiuRecord.setPokerType(gameResult.getCardType());
                coalitionNiuRecord.setCreateTime(new Date());
                records.add(coalitionNiuRecord);
            }
            coalitionNiuRecordMapper.insertList(records);
            sendMessageToAll(roomIntoReq,roomDetail,toJsonString(result),NiuAction.type11);
            //初始化数据
            init(roomDetail,roomIntoReq);
            //发送给所有人当前游戏结束
            sendMessageToAll(roomIntoReq,roomDetail,"0",NiuAction.type200);
            //如果有玩家金币小于最低入场, 则退出游戏
            Map<Integer, Object> user = new HashMap<>();
            Map<Integer, ChannelHandlerContext> chanel = new HashMap<>();
            Map<Integer, Object> userInfo = roomDetail.getUserInfo();
            Map<Integer, ChannelHandlerContext> userChanel = roomDetail.getUserChanel();
            user.putAll(userInfo);
            chanel.putAll(userChanel);
            for (Map.Entry<Integer,Object> map : user.entrySet()){
                for (Map.Entry<Integer,ChannelHandlerContext> map2 : chanel.entrySet()){
                    if (map.getKey().equals(map2.getKey())){
                        try {
                            Object coin = PropertyUtils.getProperty(map.getValue(), "coin");
                            if (niuRoomInfo.getIntoCoin().compareTo(new BigDecimal(coin.toString()))>0){ //如果小于最低房间分数,退出房间
                                Thread.sleep(2000);
                                roomIntoReq.setUserId(map.getKey());
                                quit(roomIntoReq,roomDetail,map2.getValue());
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

    }

    private void init(RoomDetail roomDetail,RoomIntoReq roomIntoReq){
        NiuNiuParamDto niuNiuParamDto = getNiuRoomInfo(roomIntoReq.getRoomId());
        Map<Integer, Object> userInfo = roomDetail.getUserInfo();
        userInfo.forEach((key,value)->{
            NiuRoomUserBaseInfo baseInfo = new NiuRoomUserBaseInfo();
            BeanUtils.copyProperties(value,baseInfo);
            if (baseInfo.getReady().equals(ReadyStatus.type2.getId())){
                baseInfo.setReady(ReadyStatus.type1.getId());baseInfo.setBets(null);baseInfo.setMaxRush(null);
                baseInfo.setBanker(null);baseInfo.setCover(null);baseInfo.setPushable("0");
                baseInfo.setStatus("0");baseInfo.setPoker(null);baseInfo.setAction(null);
                userInfo.put(key,baseInfo);
            }else { //把正在等待的玩家拉入正常准备状态
                baseInfo.setReady(ReadyStatus.type2.getId());
                ChannelHandlerContext channelHandlerContext = roomDetail.getUserChanelWatcher().get(baseInfo.getId());
                roomDetail.getPlayer().getChannelGroup().add(channelHandlerContext.channel());
                roomDetail.getUserInfo().put(baseInfo.getId(),baseInfo);
                roomDetail.getUserChanel().put(baseInfo.getId(),channelHandlerContext);
                roomDetail.getUserChanelWatcher().remove(baseInfo.getId());
                roomDetail.getWatcher().getChannelGroup().remove(channelHandlerContext.channel());
            }
        });
        roomDetail.init(niuNiuParamDto.getAdvancedOptions(),GameType.type1);
        redisTemplate.opsForHash().put(SysConstants.GAME_STATUS,roomIntoReq.getRoomId().toString(),GameStatus.type1.getId());
        roomDetail.setStatus(GameStatus.type1.getId());
    }

    private synchronized void poker(RoomIntoReq roomIntoReq,RoomDetail roomDetail,ChannelHandlerContext channelHandlerContext) {
//        chcRoom.put(channelHandlerContext,new ChcRoomInfo(roomIntoReq.getUserId(),roomIntoReq.getRoomId(),roomIntoReq.getGameType(),channelHandlerContext));
        redisTemplate.opsForHash().put(SysConstants.GAME_STATUS,roomIntoReq.getRoomId().toString(),GameStatus.type2.getId());
        redisTemplate.opsForHash().put(SysConstants.GAME_PLAYER_STATUS,roomIntoReq.getUserId().toString(),GameStatus.type2.getId());
        roomDetail.setStatus(GameStatus.type2.getId());
        setUserAction(roomIntoReq,roomDetail,NiuAction.type3);
        NiuNiuParamDto niuRoomInfo = getNiuRoomInfo(roomIntoReq.getRoomId());
        //判断是否是癞子房间, 生成牌
        GlobalData globalData = roomDetail.getGlobalData(niuRoomInfo.getAdvancedOptions(),GameType.type1);
        List<Poker> pokers = new ArrayList<>();
        List<Card> card = globalData.getCard(5);
        log.info("牌库剩余{}张",globalData.getQueue().size());
        for (Card card1 : card) {
            Poker poker = new Poker(card1.getSuitType(),card1.getFaceType());
            pokers.add(poker);
        }
        pokers.get(4).setFifth("1");
        //如果是明牌抢庄
//        if (!AdvancedOptions.type4.getId().equals(niuRoomInfo.getAdvancedOptions())){
//        }
        List<Poker> pokers1 = pokers.subList(0, 4); //只展示4张牌
        roomIntoReq.setAction(NiuAction.type3.getId());
        roomIntoReq.setActionValue(toJsonString(pokers1));
        channelHandlerContext.writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
        //存redis
        getUserInfoService.setUserPoker(pokers,roomIntoReq.getUserId());
        //发送给观战人
        roomIntoReq.setActionValue(null);
        roomDetail.getWatcher().getChannelGroup().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
        roomIntoReq.setAction(NiuAction.type200.getId());
        roomIntoReq.setActionValue("1");
        setProperty(roomIntoReq,roomDetail);
        if (MySocketUtil.finish(roomDetail,NiuAction.type200.getValue())){ //发送所有人开始游戏
            sendMessageToAll(roomIntoReq,roomDetail,"1",NiuAction.type200);
        }
    }

    private void setUserAction(RoomIntoReq roomIntoReq, RoomDetail roomDetail,NiuAction action) {
        Object o = roomDetail.getUserInfo().get(roomIntoReq.getUserId());
        try {
            PropertyUtils.setProperty(o,"action",action.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void pushInjection(RoomIntoReq roomIntoReq, RoomDetail roomDetail) {
        setProperty(roomIntoReq,roomDetail);
        MySocketUtil.sendRoomAllMessage(toJsonString(roomIntoReq),roomDetail);
    }

    private void bets(RoomIntoReq roomIntoReq, RoomDetail roomDetail) {
        Object o = setProperty(roomIntoReq, roomDetail);
        BetsDto betsDto = new BetsDto();
        betsDto.setId(roomIntoReq.getUserId());
        betsDto.setBets(roomIntoReq.getActionValue());
        sendMessageToAll(roomIntoReq,roomDetail,toJsonString(betsDto),null);
        setUserAction(roomIntoReq,roomDetail,NiuAction.type6);
        //如果金额等于推注,则发送推注消息
        Collection<NiuGameResult> roomResult = roomInfoService.getRoomResult(roomIntoReq.getRoomId(), NiuGameResult.class);
        List<NiuGameResult> collect = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roomResult)){
            collect = roomResult.stream().filter(a -> a.getId().equals(roomIntoReq.getUserId())).collect(Collectors.toList());
        }
        NiuGameResult niuGameResult1 = null;
        if (CollectionUtil.isNotEmpty(collect)){
            niuGameResult1 = collect.get(0);
            if (niuGameResult1.getPushBets().compareTo(new BigDecimal(roomIntoReq.getActionValue()))==0){ //推注
                try {
                    PropertyUtils.setProperty(o,"pushed","1");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                sendMessageToAll(roomIntoReq,roomDetail,String.valueOf(roomIntoReq.getUserId()),NiuAction.type7);
            }else {
                try {
                    PropertyUtils.setProperty(o,"pushed","0");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //如果所有人完成下注,则补全牌, 明抢补最后一张, 暗抢补全部. 数据库插入此局数据
        if (MySocketUtil.finish(roomDetail,NiuAction.type6.getValue())){
            NiuNiuParamDto niuNiuParamDto = getNiuRoomInfo(roomIntoReq.getRoomId());
            for (Map.Entry<Integer, ChannelHandlerContext> map : roomDetail.getUserChanel().entrySet()){
                try {
                    List<Poker> userPoker = getUserInfoService.getUserPoker(map.getKey());
                    List<Poker> list = new ArrayList<>();
                    if (niuNiuParamDto.getAdvancedOptions().contains(AdvancedOptions.type4.getId())){ //暗抢庄
                        roomIntoReq.setActionValue(toJsonString(userPoker));
                    }else {
                        list.add(userPoker.get(4));
                        roomIntoReq.setActionValue(toJsonString(list));
                    }
                    roomIntoReq.setUserId(map.getKey());
                    roomIntoReq.setSeat(null);
                    roomIntoReq.setAction(NiuAction.type8.getId());
                    map.getValue().channel().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
                    //发送给观战人
                    roomIntoReq.setActionValue(null);
                    roomDetail.getWatcher().getChannelGroup().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            Integer gameId = roomInfoService.getGameId();
            int maxRush = 0;
            List<NiuGameResult> niuGameResults = new ArrayList<>();
            for (Map.Entry<Integer, Object> map : roomDetail.getUserInfo().entrySet()){
                try {
                    if (PropertyUtils.getProperty(map.getValue(),"ready").toString().equals(ReadyStatus.type3.getId())){
                        continue;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                List<Poker> userPoker = getUserInfoService.getUserPoker(map.getKey());
                NiuGameResult niuGameResult = new NiuGameResult();
                BeanUtils.copyProperties(map.getValue(),niuGameResult);
                niuGameResult.setPoker(userPoker);
                NiuRoomUserBaseInfo niuRoomUserBaseInfo = new NiuRoomUserBaseInfo();
                BeanUtils.copyProperties(map.getValue(),niuRoomUserBaseInfo);
                niuGameResults.add(niuGameResult);
                if ("1".equals(niuRoomUserBaseInfo.getBanker())){  //如果是庄家, 获取抢庄倍率
                    maxRush = niuRoomUserBaseInfo.getMaxRush();
                }
            }
            getResult(niuGameResults,maxRush,roomDetail,niuNiuParamDto); //计算输赢
            for (NiuGameResult niuGameResult : niuGameResults) {
                niuGameResult.setGameId(gameId);
            }
            //存redis
            roomInfoService.setRoomResult(roomIntoReq.getRoomId(),niuGameResults);
        }
    }


    private void maxRush(RoomIntoReq roomIntoReq, RoomDetail roomDetail){
        setProperty(roomIntoReq,roomDetail);
        MaxRushDto maxRushDto = new MaxRushDto();
        maxRushDto.setId(roomIntoReq.getUserId());
        maxRushDto.setMaxRush(roomIntoReq.getActionValue());
        sendMessageToAll(roomIntoReq,roomDetail,toJsonString(maxRushDto),null);
        setUserAction(roomIntoReq,roomDetail,NiuAction.type4);
        //如果所有人都抢庄完毕, 返回庄家
        if (MySocketUtil.finish(roomDetail,NiuAction.type4.getValue())){
            Collection<Object> values = roomDetail.getUserInfo().values();
            List<NiuRoomUserBaseInfo> users = ObjectUtils.convertList(values, NiuRoomUserBaseInfo.class);
            List<NiuRoomUserBaseInfo> userBaseInfo = users.stream().filter(a -> a.getReady().equals(ReadyStatus.type2.getId())).collect(Collectors.toList());
            //选出加倍最高的人,并随机选择庄家
            List<NiuRoomUserBaseInfo> collect = userBaseInfo.stream().filter(c -> {
                return c.getMaxRush() == userBaseInfo.stream().max((a, b) -> a.getMaxRush().compareTo(b.getMaxRush())).get().getMaxRush();
            }).collect(Collectors.toList());
            Random random = new Random();
            NiuRoomUserBaseInfo niuRoomUserBaseInfo = collect.get(random.nextInt(collect.size()));
            Object o = roomDetail.getUserInfo().get(niuRoomUserBaseInfo.getId());
            try {
                PropertyUtils.setProperty(o,"banker","1");
            } catch (Exception e) {
                e.printStackTrace();
            }
            sendMessageToAll(roomIntoReq,roomDetail,String.valueOf(niuRoomUserBaseInfo.getId()),NiuAction.type5);
            //推送给最高抢庄的玩家可翻倍信息
            List<NiuRoomUserBaseInfo> collect1 = collect.stream().filter(a -> !a.getId().equals(niuRoomUserBaseInfo.getId())).collect(Collectors.toList());
            roomIntoReq.setAction(NiuAction.type13.getId());
            roomIntoReq.setActionValue(null);
            collect1.forEach(a->{
                roomDetail.getUserChanel().forEach((key,value)->{
                    if (key.equals(a.getId())){
//                        Object o1 = roomDetail.getUserInfo().get(key);
//                        try {
//                            PropertyUtils.setProperty(o1,"doubled","1");
//                        } catch (Exception e) {
//                            e.printStackTrace();
//                        }
                        value.channel().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
                    }
                });
            });
        }
    }


    private Object setProperty(RoomIntoReq roomIntoReq, RoomDetail roomDetail){
        Object o = roomDetail.getUserInfo().get(roomIntoReq.getUserId());
        String str = CommonUtils.getEnumDescById(NiuAction.class, roomIntoReq.getAction(), "getValue");
        try {
            if (!StringUtils.isEmpty(roomIntoReq.getActionValue())){
                PropertyUtils.setProperty(o,str,CommonUtils.convert(PropertyUtils.getPropertyType(o,str),roomIntoReq.getActionValue()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }

    private void ready(RoomIntoReq roomIntoReq,RoomDetail roomDetail,ChannelHandlerContext channelHandlerContext,
                       ConcurrentHashMap<ChannelHandlerContext, ChcRoomInfo> chcRoom,ConcurrentHashMap<ChannelHandlerContext, WaCherInfo> waCher){
        waCher.remove(channelHandlerContext);
        chcRoom.put(channelHandlerContext,new ChcRoomInfo(roomIntoReq.getUserId(),roomIntoReq.getRoomId(),roomIntoReq.getGameType(),channelHandlerContext));
//        setUserAction(roomIntoReq,roomDetail,NiuAction.type2);
        Object o = roomDetail.getUserInfo().get(roomIntoReq.getUserId());
        NiuNiuParamDto niuRoomInfo = getNiuRoomInfo(roomIntoReq.getRoomId());
        User user = new User();
        user.setId(roomIntoReq.getUserId());
        BigDecimal userRealTime = getUserInfoService.getUserRealTime(user);
        Integer seatNumb = roomInfoService.genSeatNumb(roomIntoReq, roomDetail, niuRoomInfo.getPeopleNumber(),PeopleNumber.class);
        NiuRoomUserBaseInfo niuRoomUserBaseInfo = new NiuRoomUserBaseInfo();
        UserVo userByUserId = getUserInfoService.getUserByUserId(roomIntoReq.getUserId());
        niuRoomUserBaseInfo.setCoin(userRealTime);
        niuRoomUserBaseInfo.setId(roomIntoReq.getUserId());
        niuRoomUserBaseInfo.setNickName(userByUserId.getNickName());
        niuRoomUserBaseInfo.setHeadImgUrl(userByUserId.getHeadImgUrl());
        niuRoomUserBaseInfo.setReady(ReadyStatus.type2.getId());
        niuRoomUserBaseInfo.setSeat(seatNumb);
        niuRoomUserBaseInfo.setAction(NiuAction.type2.name());
        if (niuRoomInfo.getIntoCoin().compareTo(userRealTime)>0){
            roomIntoReq.setAction(RoomAction.type100.getId());
            roomIntoReq.setAction(RoomAction.type100.getDesc());
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
            throw new RRException("501",RoomAction.type100.getDesc());
        }
        if (o==null){  //第一次准备
            if (seatNumb==null){
                roomIntoReq.setAction(RoomAction.type101.getId());
                roomIntoReq.setActionValue(RoomAction.type101.getDesc());
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(toJsonString(roomIntoReq)));
                throw new RRException("501",RoomAction.type101.getDesc());
            }
            if (roomDetail.getStatus().equals(GameStatus.type2.getId())){ //如果游戏已开始, 则等待结束
//                niuRoomUserBaseInfo.setReady(ReadyStatus.type3.getId());
//                roomDetail.getUserInfo().put(roomIntoReq.getUserId(),niuRoomUserBaseInfo);
                log.info("为什么会已开始？");
            }
            roomDetail.getPlayer().getChannelGroup().add(channelHandlerContext.channel());
            roomDetail.getWatcher().getChannelGroup().remove(channelHandlerContext.channel());
            roomDetail.getUserChanelWatcher().remove(roomIntoReq.getUserId());
            roomDetail.getUserInfo().put(roomIntoReq.getUserId(),niuRoomUserBaseInfo);
            roomDetail.getUserChanel().put(roomIntoReq.getUserId(),channelHandlerContext);
            //发送消息给所有人观战人数
            MySocketUtil.sendWatchCount(roomIntoReq,roomDetail);
        }else { //继续游戏
            //选出不是庄家, 并且赢了游戏的玩家
            Collection<NiuGameResult> roomResult = roomInfoService.getRoomResult(roomIntoReq.getRoomId(), NiuGameResult.class);
            List<NiuGameResult> collect = roomResult.stream().filter(a -> a.getPushBets().compareTo(new BigDecimal(0))>0).
                    filter(a->a.getId().equals(roomIntoReq.getUserId())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)){
                BigDecimal push = collect.get(0).getPushBets();
                NiuPushBetsDto pushBets = new NiuPushBetsDto();
                pushBets.setId(roomIntoReq.getUserId());
                pushBets.setPushBets(push);
                niuRoomUserBaseInfo.setPushable("1");
                sendMessageToAll(roomIntoReq,roomDetail,toJsonString(pushBets),NiuAction.type14);
            }
            roomDetail.getUserInfo().put(roomIntoReq.getUserId(),niuRoomUserBaseInfo);
        }
        //发送自己信息给所有人
        sendMessageToAll(roomIntoReq,roomDetail,toJsonString(niuRoomUserBaseInfo), NiuAction.type2);
    }



    private NiuNiuParamDto getNiuRoomInfo(Integer roomId){
        String roomDetail = roomInfoService.getRoomDetail(roomId, GameType.type1.getId());
        NiuNiuParamDto niuNiuParamDto = null;
        if (!StringUtils.isEmpty(roomDetail)){
            niuNiuParamDto = JSONObject.parseObject(roomDetail, NiuNiuParamDto.class);
        }else {
            niuNiuParamDto = niuNiuRoomMapper.selectRoomDetail(roomId);
            roomInfoService.setRoomDetail(niuNiuParamDto);
        }
        return niuNiuParamDto;
    }


    /*
    计算输赢
     */
    public void getResult(List<NiuGameResult> list,int maxRush, RoomDetail roomDetail,NiuNiuParamDto niuNiuParamDto){
        if (maxRush==0){
            maxRush =1;
        }
        int type = 1;
        if (niuNiuParamDto.getAdvancedOptions().contains(AdvancedOptions.type5.getId())){
            type = 2;
        }
        BigDecimal win = new BigDecimal(0);
        BigDecimal lose = new BigDecimal(0);
        log.info("游戏结果:{}",list);
        NiuGameResult bankResult = list.stream().filter(a -> "1".equals(a.getBanker())).collect(Collectors.toList()).get(0); //庄家
        PokerResult bankerCard = CardUtils.getPokerResult(bankResult.getPoker(), roomDetail.getGlobalData(), type,niuNiuParamDto.getSpecialCardType()); //庄家牌型
        bankResult.setPoker(bankerCard.getPokerList());
        bankResult.setCardType(bankerCard.getCardType().getId());
        List<NiuGameResult> collect = list.stream().filter(a -> (!"1".equals(a.getBanker()))).collect(Collectors.toList()); //闲家
        for (NiuGameResult gameResult : collect) {
            Object o = roomDetail.getUserInfo().get(gameResult.getId());
            NiuRoomUserBaseInfo niuRoomUserBaseInfo = new NiuRoomUserBaseInfo();
            BeanUtils.copyProperties(o,niuRoomUserBaseInfo);
            PokerResult playerCard = CardUtils.getPokerResult(gameResult.getPoker(), roomDetail.getGlobalData(), type,niuNiuParamDto.getSpecialCardType());
            gameResult.setCardType(playerCard.getCardType().getId());
            gameResult.setPoker(playerCard.getPokerList());
            //庄家赢
            if (CardUtils.compareTo(bankerCard,playerCard)>0){
                BigDecimal multiply = gameResult.getBets().multiply(new BigDecimal(maxRush)).multiply(new BigDecimal(CardUtils.getCardRate(niuNiuParamDto.getFlopRule(),bankResult.getCardType())));//下注额*庄家加倍率*庄家牌型倍率
                if (multiply.compareTo(gameResult.getCoin())>0){ //如果大于当前游戏币, 则算游戏币金额
                    multiply = gameResult.getCoin();
                }
                gameResult.setLose(multiply);
                gameResult.setResult(GameResult.type1.getId());
                win = win.add(multiply);
            }
            else { //庄家输
                BigDecimal multiply = gameResult.getBets().multiply(new BigDecimal(maxRush)).multiply(new BigDecimal(CardUtils.getCardRate(niuNiuParamDto.getFlopRule(),gameResult.getCardType())));//下注额*庄家加倍率*玩家牌型倍率
                gameResult.setWin(multiply);
                gameResult.setResult(GameResult.type2.getId());
                lose = lose.add(multiply);
                if ((!niuNiuParamDto.getPushInjection().equals(PushInjection.type1.getId()))&&niuRoomUserBaseInfo.getPushed().equals("0")){ //如果房间规则可推注,并且上一把没推注, 则添加推注金额
                    Integer value = PushInjection.getValueById(niuNiuParamDto.getPushInjection());
                    BigDecimal push = multiply.multiply(new BigDecimal(value));
                    String bets = Bets.getDescById(niuNiuParamDto.getBets()).split("/")[3];
                    if (push.compareTo(new BigDecimal(bets).multiply(new BigDecimal(value)))>=0){
                        push = new BigDecimal(bets).multiply(new BigDecimal(value)).setScale(0,BigDecimal.ROUND_UP);
                    }
                    gameResult.setPushBets(push);
                }
            }
        }
        if (win.compareTo(lose)<0 && lose.subtract(win).compareTo(bankResult.getCoin())>0){ //如果庄家输多赢少,并且输的金额大于庄家现有金额,则优先发给牌最大的人,直到为0
            BigDecimal rest = bankResult.getCoin().add(win);
            bankResult.setLose(rest);
            //排序赢的闲家的牌大小---从大到小
            List<NiuGameResult> losePlayer = collect.stream().filter(a->a.getResult().equals(GameResult.type1.getId())).collect(Collectors.toList());
            List<NiuGameResult> winPlayer = collect.stream().filter(a->a.getResult().equals(GameResult.type2.getId())).sorted(new Comparator<NiuGameResult>() {
                @Override
                public int compare(NiuGameResult o1, NiuGameResult o2) {
                    return Integer.valueOf(o1.getCardType()) - Integer.valueOf(o2.getCardType());
                }
            }).collect(Collectors.toList());
            for (NiuGameResult gameResult : winPlayer) {
                Object o = roomDetail.getUserInfo().get(gameResult.getId());
                NiuRoomUserBaseInfo niuRoomUserBaseInfo = new NiuRoomUserBaseInfo();
                BeanUtils.copyProperties(o,niuRoomUserBaseInfo);
                if (rest.intValue()==0){
                    gameResult.setWin(new BigDecimal(0));
                    continue;
                }
                if (gameResult.getWin().compareTo(rest)>=0){
                    gameResult.setWin(rest);
                    if ((!niuNiuParamDto.getPushInjection().equals(PushInjection.type1.getId()))&&niuRoomUserBaseInfo.getPushed().equals("0")){ //如果房间规则可推注,并且上一把没推注, 则添加推注金额
                        gameResult.setPushBets(rest.multiply(new BigDecimal(PushInjection.getValueById(niuNiuParamDto.getPushInjection()))));
                    }
                    rest = new BigDecimal(0);
                }else {
                    if ((!niuNiuParamDto.getPushInjection().equals(PushInjection.type1.getId()))&&niuRoomUserBaseInfo.getPushed().equals("0")){ //如果房间规则可推注,并且上一把没推注, 则添加推注金额
                        gameResult.setPushBets(gameResult.getWin().multiply(new BigDecimal(PushInjection.getValueById(niuNiuParamDto.getPushInjection()))));
                    }
                    rest = rest.subtract(gameResult.getWin());
                }
            }
            list.clear();
            list.add(bankResult);
            list.addAll(losePlayer);
            list.addAll(winPlayer);
        }else {
            if (win.compareTo(lose)>=0){
                bankResult.setWin(win.subtract(lose));
            }else {
                bankResult.setLose(lose.subtract(win));
            }
            list.clear();
            list.add(bankResult);
            list.addAll(collect);
        }
    }

    private void sendMessageToAll(RoomIntoReq roomIntoReq,RoomDetail roomDetail,String message,NiuAction niuAction){
        RoomInfoResp roomInfoResp = new RoomInfoResp();
        BeanUtils.copyProperties(roomIntoReq,roomInfoResp);
        if (niuAction!=null){
            roomInfoResp.setAction(niuAction.getId());
        }
        roomInfoService.sendChanel(roomDetail, message, roomInfoResp);
    }

}
